With the introduction of if statements.
There's another fundamental concept in programming I'd like to cover called lexical scope.
Lexical scope, also called scope for short, is a region in your code where a particular variable or
identifier is visible and can be accessed.
Scope determines which variables our interpreter can see and interact with.
A great example would be to imagine a building with multiple rooms and each room containing a window.
You can imagine the interpreter as someone walking outside the building and looking through the window
in each room.
Each room represents a different scope that our interpreter can look into.
For example, one room can be a kitchen and our interpreter can see knives, food, and other stuff
relating to the kitchen.
However, if our interpreter walks to the next window and sees a bathroom inside, it can no longer
see the stuff inside of the kitchen like the knives in the food.
Instead, it sees an entirely new scope with different stuff inside of it.
To demonstrate scope, I'm going to create a new variable called where am I?
So we can do where am I?
And for now I'm going to set this equal to a string like the bathroom.
Now.
By default, this variable is accessible within the entire scope of our script.
This is also known as the global scope.
To restrict a variable to a specific scope, we use something called the local keyword in Lua.
So before we create the identifier for our variable, we can type out the local keyword.
And now we have restricted this variable to the scope where it was created.
Now doing this and doing this is the same thing, because we're both declaring the variable within the
entire global scope of the script, so there's no difference in doing it.
However, using the local keyword is absolutely crucial to help us see where variables are being created
or instantiated, and differentiate that from where values inside of our variable is being overridden.
For example, here we know that a variable is being created.
But if I do something like this and I set the value inside of where am I to something like kitchen.
We aren't creating a variable here.
Instead, what we're doing is we're referring to the already existing variable that we've created up
here, and we're overriding the value inside of it to be equal to this new string right here.
So this isn't creating a variable, it's simply overriding the value inside of a variable that was already
created.
But if we never use the local keyword, it can kind of be difficult to see where we're creating our
variable and where we are overriding the value inside of our variable.
So using the local keyword is a great practice to help us read our code more easily and see exactly
where variables are being created, and where variables are having the values inside of them be overridden
with a new value.
Now, what I'm going to do is I'm going to create an if statement.
And I'm going to check if the value inside of where am I is equal to something like the bathroom.
If it is, then we're going to have the interpreter hop inside of this block of code right here, which
is a brand new scope.
And we know this is a brand new scope because the N keyword has popped up here to denote the end of
a new scope.
So this is our new scope in here.
You can imagine this as another room inside of our building.
And what I'm going to do in here is I'm going to create another variable.
And I'm going to call this variable like knife.
And I'm going to set it equal to a string like sharp.
We'll just do something like that.
Now to restrict this variable inside of this if statement block or this scope, I'm going to put the
local keyword.
This means anywhere outside of this block of code.
I cannot see this knife variable.
If I try to type out knife here, the interpreter is not going to have any idea what I'm talking about.
If I got rid of that local keyword and I type out knife now it is able to see knife and I can autofill
it automatically.
But if I put the local keyword I have now restricted knife to this particular scope.
We can also add another else if statement here and pass another condition so we can check if where am
I.
Let's say we're in the kitchen.
So if the string inside of where am I is equal to kitchen, then inside of here we can create a toilet.
Or actually now I have it flipped around.
We should create the knife inside of the kitchen and then we'll create the toilet inside of the bathroom.
My mistake.
And we'll just set this equal to a string like flush or something like that.
And now we have two completely different scopes.
We have one scope here and we have one scope here.
Neither of these scopes can see the other variable created in the other scope.
So for example in this scope here I can't see toilet.
It doesn't exist for me.
And inside of this scope here I can't see knife A because I'm not in the same scope, and B the variable
is created after the interpreter executes this code up here.
So it's technically impossible to see this knife variable.
But just for the sake of explanation, these two scopes have no idea of the other stuff in the other
scope, right?
If I'm in the bathroom, I don't know about the knife in the kitchen, and if I'm in the kitchen, I
have no idea about the toilet in the bathroom.
And if I am outside of both of those rooms, then I have no idea of neither the knife or the toilets
existence.
Right?
If I type out knife, it doesn't know, and if I type out toilet, it doesn't know about that either.
So this is the main idea of scope, where we restrict or hide variables and identifiers to their particular
scope.
It is always a good practice to use the local keyword.
When you are creating your variables, you always want to restrict your variables to the scope that
they belong inside of.
So understanding and implementing lexical scope is absolutely critical for writing maintainable and
bug free code.
It helps to prevent unintended interactions between variables, and it also ensures that variables are
accessible where they are needed.
It's always best practice to use the local keyword when you are creating a variable to ensure that the
only exist within their respective scopes.
Now, one last very important thing I'd like to mention with lexical scope is how different variables
take higher precedence over other variables, depending on what scope you're in.
You might not understand what I mean, but I'm going to show you it here in a moment.
So if I got rid of the local keyword here for my where am I?
Variable and left it as default.
So it's global to the entire script, right.
We access where am I and check to see if we're in the bathroom.
If we're in the bathroom, then what I'm going to do in here is I'm going to create a new variable.
I'm going to use the local keyword, but this time I'm going to use the exact same name as this variable
here.
So if I do where am I and set this equal to something else like let's say I am, let's say I'm in the
toilet, right?
Let's just do something like that.
And then I go and print out where am I here?
And then I go down to the bottom of my script and print out where am I?
What do you think is going to print in these two if statements?
Well, we can go ahead and run the game and quickly figure this out.
So if we hit run here.
The first print statement printed out toilet, but the second print statement printed out bathroom.
Interesting, right?
So if we go back into our script.
This first one here printed out toilet and this second one here printed out bathroom.
Now this is because since we created a new variable in here, even though it has the exact same name,
these two variables are actually being treated as different.
So we created this new local variable.
Even though it has the same name.
This variable takes higher precedence over this variable out here because we are inside of this scope.
So when we use this print statement we are actually referring to this locally created where am I variable
and not this globally created?
Where am I variable.
However, outside of that particular bathroom scope, when we use the print statement down here, we
print out the bathroom string as expected.
But of course up in here, since this local variable took higher precedent, it printed out toilet.
So that's a very important thing you have to understand with scope is that when you create variables
with the same name but restrict them to their scopes, they will take higher precedence over any other
variables that were created in a more, you know, global scope.
Now, you will usually never run into this problem because a you should never, ever name your variables
the exact same thing.
You should always give them a different name, because if you name variables the same thing, you're
just bound to run into problems.
But this is just a quick example of how the interpreter executes and sets the priority for different
variables depending on the scope that they're created in.
See you in the next lecture.